package com.swing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.apache.commons.lang3.StringUtils;

import com.config.OrmFile;
import com.entity.MavenItem;
import com.entity.OrmFileRes;
import com.entity.OrmInfoFile;
import com.entity.OrmJdbcFile;
import com.service.MainFun;
import com.utils.DruidTool;
import com.utils.JdbcTable;
import com.utils.JdbcTableColumn;
import com.utils.MySqlJdbcType;
import com.utils.MysqlColumn;
import com.utils.MysqlTable;
import com.utils.OrmException;
import com.utils.RegexpUtil;
import com.utils.StrUtil;

public class MainUi extends UiJFrame {
	
	DruidTool druidTool = null;
	
	OrmInfoFile ormInfoFile = null;
	/**
	 * 
	 */
	private static final long serialVersionUID = 609156289350641712L;
 
	@SuppressWarnings("deprecation")
	public MainUi() {
		setTitle("JLOrm代码自动化_V1.0");
		setSize(540, 740);
		//setLocation(400, 400);
		jFrame.setBackground(Color.RED);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null); // 居中显示
        //setAlwaysOnTop(true);//将弹窗放在最前面
		setLayout(new GridLayout(12, 2));
		
		JMenuBar menuBar = new JMenuBar();
		JMenu aboutMenu = new JMenu("菜单");
		JMenuItem menuItem1 = new JMenuItem("数据库配置文件");
		JMenuItem menuItem2 = new JMenuItem("系统配置文件");
		JMenuItem menuItem3 = new JMenuItem("关于JLOrm");
		aboutMenu.add(menuItem1);
		aboutMenu.add(menuItem2);
		aboutMenu.add(menuItem3);
        JMenu versionMenu = new JMenu("帮助");
		JMenuItem menuItem4 = new JMenuItem("版本");
		JMenuItem menuItem5 = new JMenuItem("运行日志");
		versionMenu.add(menuItem4);
		versionMenu.add(menuItem5);
        menuBar.add(aboutMenu);
        menuBar.add(versionMenu);
        
        jFrame.setJMenuBar(menuBar);
        
		OrmFileRes<OrmInfoFile> res = OrmFile.readOrm();
		if (res.getStatus() == 0) {
    		error("配置读取失败");
    		setVisible(false);
    		return;
		}
		ormInfoFile = res.getData();
		
		JPanel titleJPanel = new JPanel();
		JPanel domainDirJPanel = new JPanel();
		JPanel daoDirJPanel = new JPanel();
		JPanel mapperDirJPanel = new JPanel();
		JPanel mavenJPanel = new JPanel();
		JPanel moduleJPanel = new JPanel();
		JPanel tableJPanel = new JPanel();
		JPanel daoJPanel = new JPanel();
		JPanel entityJPanel = new JPanel();
		JPanel mapperJPanel = new JPanel();
		JPanel authorJPanel = new JPanel();
		JPanel btnJPanel = new JPanel();
	    
		JLabel titleLabel = new JLabel("JLOrm代码自动化_V1.0（摩比内部使用）", JLabel.CENTER);

		JButton domainDirBtn = new JButton("领域目录  ");
		domainDirBtn.setPreferredSize(new Dimension(100,30));
		JButton daoDirBtn =    new JButton("DAO目录  ");
		daoDirBtn.setPreferredSize(new Dimension(100,30));
		JButton mapperDirBtn = new JButton("MP目录     ");
		mapperDirBtn.setPreferredSize(new Dimension(100,30));
		JLabel mavenLabel =    new JLabel("类型              ", JLabel.LEFT);
		mavenLabel.setPreferredSize(new Dimension(100,30));
		JLabel entityLabel =   new JLabel("domain包", JLabel.LEFT);
		entityLabel.setPreferredSize(new Dimension(100,30));
		JLabel daoLabel =      new JLabel("dao包          ", JLabel.LEFT);
		daoLabel.setPreferredSize(new Dimension(100,30));
		JLabel mapperLabel =   new JLabel("mapper包 ", JLabel.LEFT);
		mapperLabel.setPreferredSize(new Dimension(100,30));
		JLabel moduleLabel =   new JLabel("模块                  ", JLabel.LEFT);
		moduleLabel.setPreferredSize(new Dimension(100,30));
		JLabel tableLabel =    new JLabel("表名                  ", JLabel.LEFT);
		tableLabel.setPreferredSize(new Dimension(100,30));
		JLabel authorLabel =   new JLabel("码农                  ");
		authorLabel.setPreferredSize(new Dimension(100,30));

	    
		JLabel _domainDirField = new JLabel("项目domain目录                          ", JLabel.LEFT);
		_domainDirField.setForeground(new Color(138,149,116));
		JLabel _daoDirField =    new JLabel("项目dao目录                                   ", JLabel.LEFT);
		_daoDirField.setForeground(new Color(138,149,116));
		JLabel _mapperDirField = new JLabel("项目mapper目录                          ", JLabel.LEFT);
		_mapperDirField.setForeground(new Color(138,149,116));
		JLabel _mavenLabel =     new JLabel("决定src/main/java     ", JLabel.LEFT);
		_mavenLabel.setForeground(new Color(138,149,116));
		JLabel _entityLabel =    new JLabel("com.wymbkj.domain    ", JLabel.LEFT);
		_entityLabel.setForeground(new Color(138,149,116));
		JLabel _daoLabel =       new JLabel("com.wymbkj.dao       ", JLabel.LEFT);
		_daoLabel.setForeground(new Color(138,149,116));
		JLabel _mapperLabel =    new JLabel("com.wymbkj.mapper    ", JLabel.LEFT);
		_mapperLabel.setForeground(new Color(138,149,116));
		JLabel _moduleLabel =    new JLabel("空则不分模块                                        ", JLabel.LEFT);
		_moduleLabel.setForeground(new Color(138,149,116));
		JLabel _tableLabel =     new JLabel("必填                                                        ", JLabel.LEFT);
		_tableLabel.setForeground(new Color(138,149,116));
		JLabel _authorLabel =    new JLabel("作者                                                        ", JLabel.LEFT);
		_authorLabel.setForeground(new Color(138,149,116));
		
		JButton jdbcBtn = new JButton("配置数据库");
		JButton createBtn = new JButton("生成代码");
		JButton closeBtn = new JButton("关闭退出");
		
		JTextField domainDirField = new JTextField(res.getData().getDomainPath());
		domainDirField.setPreferredSize(new Dimension(300,30));
		domainDirField.disable();
		JTextField daoDirField = new JTextField(res.getData().getDaoPath());
		daoDirField.setPreferredSize(new Dimension(300,30));
		daoDirField.disable();
		JTextField mapperDirField = new JTextField(res.getData().getMapperPath());
		mapperDirField.setPreferredSize(new Dimension(300,30));
		mapperDirField.disable();
        //JTextField mavenField = new JTextField(res.getData().getModule());
        JComboBox<MavenItem> mavenField = new JComboBox<MavenItem>();
        mavenField.setPreferredSize(new Dimension(300,30));
        mavenField.addItem(new MavenItem(1,"maven项目"));
        mavenField.addItem(new MavenItem(0,"普通项目"));
        JTextField domainField = new JTextField(res.getData().getEntity());
        domainField.setPreferredSize(new Dimension(300,30));
        JTextField daoField = new JTextField(res.getData().getDao());
        daoField.setPreferredSize(new Dimension(300,30));
        JTextField mapperField = new JTextField(res.getData().getMapper());
        mapperField.setPreferredSize(new Dimension(300,30));
        JTextField moduleField = new JTextField(res.getData().getModule());
        moduleField.setPreferredSize(new Dimension(300,30));
        JTextField tableField = new JTextField(res.getData().getTable());
        tableField.setPreferredSize(new Dimension(300,30));
        JTextField authorField = new JTextField(res.getData().getAuthor());
        authorField.setPreferredSize(new Dimension(300,30));


		jdbcBtn.setBackground(new Color(22, 159, 229));
		jdbcBtn.setForeground(Color.WHITE);
		
		
		createBtn.setBackground(new Color(220, 53, 69));
		createBtn.setForeground(Color.WHITE);
		
		closeBtn.setBackground(Color.WHITE);

		titleJPanel.add(titleLabel);

		domainDirJPanel.add(domainDirBtn);
		domainDirJPanel.add(domainDirField);
		domainDirJPanel.add(_domainDirField);

		daoDirJPanel.add(daoDirBtn);
		daoDirJPanel.add(daoDirField);
		daoDirJPanel.add(_daoDirField);

		mapperDirJPanel.add(mapperDirBtn);
		mapperDirJPanel.add(mapperDirField);
		mapperDirJPanel.add(_mapperDirField);

		mavenJPanel.add(mavenLabel);
		mavenJPanel.add(mavenField);
		mavenJPanel.add(_mavenLabel);

		entityJPanel.add(entityLabel);
		entityJPanel.add(domainField);
		entityJPanel.add(_entityLabel);

		daoJPanel.add(daoLabel);
		daoJPanel.add(daoField);
		daoJPanel.add(_daoLabel);

		mapperJPanel.add(mapperLabel);
		mapperJPanel.add(mapperField);
		mapperJPanel.add(_mapperLabel);

		moduleJPanel.add(moduleLabel);
		moduleJPanel.add(moduleField);
		moduleJPanel.add(_moduleLabel);

		tableJPanel.add(tableLabel);
		tableJPanel.add(tableField);
		tableJPanel.add(_tableLabel);

		authorJPanel.add(authorLabel);
		authorJPanel.add(authorField);
		authorJPanel.add(_authorLabel);

		btnJPanel.add(jdbcBtn);
		btnJPanel.add(createBtn);
		btnJPanel.add(closeBtn);

		add(titleJPanel);
		add(domainDirJPanel);
		add(daoDirJPanel);
		add(mapperDirJPanel);
		add(mavenJPanel);
		add(entityJPanel);
		add(daoJPanel);
		add(mapperJPanel);
		add(moduleJPanel);
		add(tableJPanel);
		add(authorJPanel);
		
		add(btnJPanel);
	
		
		setVisible(true);
		
		createBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String domainDir = domainDirField.getText();
				String daoDir = daoDirField.getText();
				String mapperDir = mapperDirField.getText();
	        	String moduleVal = moduleField.getText();
	        	String tableVal = tableField.getText();
	        	String domainPg = domainField.getText();
	        	String daoPg = daoField.getText();
	        	String mapperPg = mapperField.getText();
	        	String authorVal = authorField.getText();
	        	if (StrUtil.isEmpty(domainDir)) {
	        		error("请选择领域磁盘目录");
	        		return;
				}
	        	if (!StrUtil.isEmpty(domainPg)) {
	        		if (!RegexpUtil.validPg(domainPg)) {
		        		error("domain包正则失败：[只包含：英文  .  ]");
		        		return;
					}
	        	}
	        	if (!StrUtil.isEmpty(daoPg)) {
	        		if (!RegexpUtil.validPg(daoPg)) {
		        		error("dao包正则失败：[只包含：英文  .  ]");
		        		return;
					}
	        	}
	        	if (!StrUtil.isEmpty(mapperPg)) {
	        		if (!RegexpUtil.validPg(mapperPg)) {
		        		error("mapper包正则失败：[只包含：英文  .  ]");
		        		return;
					}
	        	}
	        	String[] tableValArr = tableVal.split("\\s+");
	        	List<String> tables = new ArrayList<>();
	        	for (String string : tableValArr) {
	        		string = StringUtils.deleteWhitespace(string);
	        		if (!StrUtil.isEmpty(string)) {
	        			if (!RegexpUtil.validName(string)) {
	    	        		error(string + "表名正则失败：[只包含：  英文  _  -  ]");
	    	        		return;
	    				}
	        			tables.add(string);
	        		}
				}
	        	if (StrUtil.isEmpty(tables)) {
	        		error("请输入表名");
	        		return;
				}
	        	if (StrUtil.isEmpty(authorVal)) {
	        		authorVal = "码农小鹿";
				}
	        	OrmFileRes<OrmJdbcFile> res = OrmFile.readJdbc();
	        	if (res.getStatus() == 0) {
	        		error("数据库配置读取失败");
	        		return;
				}
	        	if (!StrUtil.isEmpty(moduleVal)) {
	        		if (!RegexpUtil.validPg(moduleVal)) {
		        		error("模块正则失败：[只包含：英文  .  ]");
		        		return;
					}
	        	}
	        	String title = "点击确认开始生成";
	        	if (!StrUtil.isEmpty(mapperDir)) {
	        		title = "已选择mapper，请小心代码覆盖";
				}
	        	int dialogRes = JOptionPane.showConfirmDialog(jFrame, title, "提示", JOptionPane.OK_CANCEL_OPTION);
	        	if (dialogRes == 2) {
	        		warning("已取消生成");
	        		return;
				}
	        	MavenItem mavenItem = (MavenItem) mavenField.getSelectedItem();
	        	OrmFile.saveConfig(
	        			domainDir,
	        			daoDir,
	        			mapperDir,
	        			mavenItem.getId(),
	        			moduleVal,
	        			tableVal,
	        			daoPg,
	        			domainPg,
	        			mapperPg,
	        			authorVal
	        			);
	        	try {
	        		if(null == druidTool || druidTool.getDataSource().isClosed()) {
	        			druidTool = new DruidTool(res.getData());
	        		}
				} catch (SQLException e1) {
					error("数据库连接失败：" + e1.getMessage());
	        		return;
				}
	        	List<JdbcTable> jdbcTables = new ArrayList<JdbcTable>();
	        	StringBuffer sb = new StringBuffer();
	        	for (String tableName : tables) {
	        		JdbcTable tableInfo = druidTool.getTable(tableName);
		        	if (null != tableInfo) {
		        		sb.append(tableName);
		        		jdbcTables.add(tableInfo);
					}
				}
	        	if (StrUtil.isEmpty(jdbcTables)) {
	        		error("无法查询到匹配的表");
	        		return;
				}
	        	//warning("已将生成的表数据：" + sb.toString());
	        	for (JdbcTable jdbcTable : jdbcTables) {
	        		List<JdbcTableColumn> cList = druidTool.getTableCloumns(jdbcTable.getName());
	        		jdbcTable.setColumnList(cList);
	        	}
	        	List<MysqlTable> mysqlTables = new ArrayList<MysqlTable>();
	        	for (JdbcTable jdbcTable : jdbcTables) {
	        		MysqlTable table = new MysqlTable();
		    		table.setTableName(jdbcTable.getName());
		    		table.setTableComment(jdbcTable.getRemark());
		    		table.setClassName(StrUtil.toCamel(jdbcTable.getName()));
		    		table.setNormalName(StrUtil.toFirstLow(table.getClassName()));
		    		if (StrUtil.isEmpty(moduleVal)) {
			    		table.setModuleName("");
			    		table.setModulePoin("");
					}else {
			    		table.setModuleName(moduleVal);
			    		table.setModulePoin(".");
					}
		    		domainPg = StrUtil.isEmpty(domainPg)?"":domainPg;
		    		daoPg = StrUtil.isEmpty(daoPg)?"":daoPg;
		    		mapperPg = StrUtil.isEmpty(mapperPg)?"":mapperPg;
		    		table.setDomainPackage(domainPg);
		    		table.setDaoPackage(daoPg);
		    		table.setMapperPackage(mapperPg);
		    		
		    		List<MysqlColumn> columns = new ArrayList<MysqlColumn>();
		    		
		    		Map<String, String> importMap = new HashMap<String, String>();
		    		for (JdbcTableColumn column : jdbcTable.getColumnList()) {
		    			MysqlColumn column1 = new MysqlColumn();
			    		column1.setColumnName(column.getName());
			    		column1.setColumnComment(column.getRemark());
			    		column1.setColumnType(column.getXmlType());
			    		column1.setIsPk(column.getIsKey()==1?true:false);
			    		column1.setJavaType(column.getJavaType());
			    		column1.setJavaField(StrUtil.toFirstLow(StrUtil.toCamel(column.getName())));

			    		columns.add(column1);
			    		if (column.getIsKey()==1) {
			    			table.setPkColumn(column1);
						}
			    		if ("Date".equals(column.getJavaType()) || "Timestamp".equals(column.getJavaType())) {
			    			column1.setIsDate(true);
						}
			    		column1.setIsNum(MySqlJdbcType.isNum(column.getSqlType()));
			    		String needImp = MySqlJdbcType.validImport(column.getJavaType());
			    		if (!StrUtil.isEmpty(needImp)) {
			    			importMap.put(needImp, needImp);
						}
					}
		    		List<String> imports = importMap.keySet().stream().collect(Collectors.toList());
		    		table.setImports(imports);
		    		table.setColumns(columns);
		    		mysqlTables.add(table);
	        	}
	        	StringBuffer errSb = new StringBuffer();
	        	for (MysqlTable table : mysqlTables) {
	        		try {
	        			new MainFun(domainDir, daoDir, mapperDir,
								mavenItem.getId(),
								table, authorVal).init();
					} catch (OrmException ue) {
						errSb.append(table.getTableName() + "表生成异常：" + ue.getMessage());
					}
	        	}
	        	if (StrUtil.isEmpty(errSb.toString())) {
	        		ok("生成成功，请刷新项目代码");
				}else {
					error("已生成，但存在异常数据：" + errSb.toString());
				}
        		return;
			}
		});
		closeBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				int dialogRes = JOptionPane.showConfirmDialog(jFrame, "是否退出？", "提示", JOptionPane.OK_CANCEL_OPTION);
	        	if (dialogRes == 0) {
	        		if (null != druidTool) {
						druidTool.close();
					}
					System.exit(0);
	        		return;
				}
			}
		});
		jdbcBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				//error("请使用配置方式，暂不开放");
        		//return;
				new JdbcUi(jFrame, druidTool);
			}
		});
		domainDirBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser jfc =new JFileChooser(ormInfoFile.getDomainPath());
				jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY );
				jfc.showDialog(new JLabel(), "选择领域路径");
				File file=jfc.getSelectedFile();
				if(null != file && file.isDirectory()){
					domainDirField.setText(file.getAbsolutePath());
				}else {
					domainDirField.setText("");
				}
			}
		});
		daoDirBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser jfc =new JFileChooser(ormInfoFile.getDaoPath());
				jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY );
				jfc.showDialog(new JLabel(), "选择DAO路径");
				File file=jfc.getSelectedFile();
				if(null != file && file.isDirectory()){
					daoDirField.setText(file.getAbsolutePath());
				}else {
					daoDirField.setText("");
				}
			}
		});
		mapperDirBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				JFileChooser jfc =new JFileChooser(ormInfoFile.getMapperPath());
				jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY );
				jfc.showDialog(new JLabel(), "选择MAPPER路径");
				File file = jfc.getSelectedFile();
				if(null != file && file.isDirectory()){
					mapperDirField.setText(file.getAbsolutePath());
				}else {
					mapperDirField.setText("");
				}
			}
		});

		menuItem1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            	ok("C:\\orm\\orm.config");
            }
        });

		menuItem2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            	ok("C:\\orm\\jdbc.config");
            }
        });

		menuItem3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            	new AboutUi(jFrame);
            }
        });

		menuItem4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ok("欢迎使用JLOrm测试版：v_1.0  By:码农小鹿");
            }
        });

		menuItem5.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            	new LogUi(jFrame);
            }
        });
	}
}
